﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace OWLServer.owl.tipos
{
    /// <summary>
    /// Clase que representa una restricción
    /// </summary>
    public class Restriccion
    {
        private int idBBDD;
        private TipoRestriccion tipo;
        private TipoPropiedadRelacionada tipoPropiedadRelacionada;
        private int cardinalidad;
        private Clase clase;

        /// <summary>
        /// Id con el que se almacena en la Base de Datos
        /// </summary>
        public virtual int IdBBDD
        {
            get { return idBBDD; }
            set { idBBDD = value; }
        }

        /// <summary>
        /// Propiedad de un elemento con la que vamos a relacionar la Restriccion
        /// </summary>
        public virtual TipoPropiedadRelacionada TipoPropiedadRelacionada
        {
            get { return tipoPropiedadRelacionada; }
            set { tipoPropiedadRelacionada = value; }
        }

        /// <summary>
        /// Tipo de restricción que vamos a aplicar.
        /// </summary>
        public virtual TipoRestriccion Tipo
        {
            get { return tipo; }
            set { tipo = value; }
        }

        /// <summary>
        /// Cardinalidad que vamos que restringe.
        /// </summary>
        public virtual int Cardinalidad
        {
            get { return cardinalidad; }
            set { cardinalidad = value; }
        }

        /// <summary>
        /// Clase que vamos que restringe.
        /// </summary>
        public virtual Clase Clase
        {
            get { return clase; }
            set { clase = value; }
        }

        /// <summary>
        /// Restricción que vamos a aplicar sobre una clase. Que afecta a una propiedad relacionadad con la misma.
        /// </summary>
        public Restriccion(){
            Tipo = TipoRestriccion.SIN_DEFINIR;
        }

        /// <summary>
        /// Restricción que vamos a aplicar sobre una clase. Que afecta a una propiedad relacionadad con la misma.
        /// </summary>
        /// <param name="tipo">Tipo de restricción.</param>
        /// <param name="tipoPropiedadRelacionada">Propiedad de un elemento con la que vamos a relacionar la Restriccion</param>
        /// <param name="cardinalidad">Cardinalidad relacionada con la restriccion</param>
        public Restriccion(TipoRestriccion tipo, TipoPropiedadRelacionada tipoPropiedadRelacionada, int cardinalidad)
        {
            Tipo = tipo;
            TipoPropiedadRelacionada = tipoPropiedadRelacionada;
            Cardinalidad = cardinalidad;
        }

        /// <summary>
        /// Restricción que vamos a aplicar sobre una clase. Que afecta a una propiedad relacionadad con la misma.
        /// </summary>
        /// <param name="tipo">Tipo de restricción.</param>
        /// <param name="tipoPropiedadRelacionada">Propiedad de un elemento con la que vamos a relacionar la Restriccion</param>
        /// <param name="clase">Clase relacionada con la restriccion</param>
        public Restriccion(TipoRestriccion tipo, TipoPropiedadRelacionada tipoPropiedadRelacionada, Clase clase)
        {
            Tipo = tipo;
            TipoPropiedadRelacionada = tipoPropiedadRelacionada;
            Clase = clase;
        }
    }

    /// <summary>
    /// Tipos de propiedades a las que vamos a aplicar la restricción, dentro de la clase.
    /// </summary>
    public enum TipoPropiedadRelacionada : int
    {
        /// <summary>
        /// Relacionada con la propiedad SubClase de una clase
        /// </summary>
        CLASE_SUBCLASE,
        /// <summary>
        /// Relacionada con la propiedad de equivalencia de clases
        /// </summary>
        CLASE_EQUIVALENTE,
        /// <summary>
        /// Relacionada con la propiedad dato de dominio de propiedad
        /// </summary>
        PROPIEDAD_DATO_DOMINIO,
        /// <summary>
        /// Relacionada con la propiedad objeto de dominio de propiedad
        /// </summary>
        PROPIEDAD_OBJETO_DOMINIO,
        /// <summary>
        /// Relacionada con la propiedad objeto de rango de propiedad
        /// </summary>
        PROPIEDAD_OBJETO_RANGO,
        /// <summary>
        /// Relacionada con la propiedad de tipo de individuo
        /// </summary>
        INDIVIDUO_TIPO
    }

    /// <summary>
    /// Tipo de Restricción que vamos a aplicar.
    /// </summary>
    public enum TipoRestriccion : int
    {
        /// <summary>
        /// Tipo Sin definir.
        /// </summary>
        SIN_DEFINIR,
        /// <summary>
        /// Todos los individuos con los que relacionemos esa propiedad tienen que ser de la clase indicada.
        /// </summary>
        TODOS_LOS_VALORES_DE,
        /// <summary>
        /// Alguno de los individuos con los que relacionemos esa ropiedad tienen que ser de la clase indicada.
        /// </summary>
        ALGUNOS_VALORES_DE,
        /// <summary>
        /// hasValue nos permite especificar las clases basadas en la existencia de valores de propiedad particular. Por lo tanto, un individuo será un miembro de esa clase cada vez que al menos uno de los valores de su propiedad es igual a la de los recursos hasValue.
        /// </summary>
        TIENE_UN_VALOR,
        /// <summary>
        /// Indica el número exacto de elementos, de un tipo concreto tiene una propiedad.
        /// </summary>
        CARDINALIDAD,
        /// <summary>
        /// Indica el número minimo de elementos, de un tipo concreto tiene una propiedad.
        /// </summary>
        CARDINALIDAD_MINIMA,
        /// <summary>
        /// Indica el número maximo de elementos, de un tipo concreto tiene una propiedad.
        /// </summary>
        CARDINALIDAD_MAXIMA
    }
}
